using FileManager.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;

namespace FileManager.Services
{
    public class FileManagerService
    {
        private readonly AppDbContext _dbContext;

        public FileManagerService(AppDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        #region 文件查询方法

        public async Task<List<FileItem>> GetAllFilesAsync(int limit = 100)
        {
            return await _dbContext.Files
                .OrderByDescending(f => f.CreateTime)
                .Take(limit)
                .ToListAsync();
        }

        public async Task<List<FileItem>> GetFilesByTypeAsync(string fileType)
        {
            return await _dbContext.Files
                .Where(f => f.FileType == fileType)
                .OrderByDescending(f => f.CreateTime)
                .ToListAsync();
        }

        public async Task<List<FileItem>> GetFilesByChatObjectAsync(int chatObjectId)
        {
            return await _dbContext.FileChatRelations
                .Where(r => r.ChatObjectId == chatObjectId)
                .Include(r => r.File)
                .Select(r => r.File)
                .OrderByDescending(f => f.CreateTime)
                .ToListAsync();
        }

        public async Task<List<FileItem>> GetFilesByTagAsync(int tagId)
        {
            return await _dbContext.FileTagRelations
                .Where(ft => ft.TagId == tagId)
                .Include(ft => ft.File)
                .Select(ft => ft.File)
                .OrderByDescending(f => f.CreateTime)
                .ToListAsync();
        }

        public async Task<List<FileItem>> GetImportantFilesAsync()
        {
            return await _dbContext.Files
                .Where(f => f.IsImportant)
                .OrderByDescending(f => f.CreateTime)
                .ToListAsync();
        }

        public async Task<List<FileItem>> SearchFilesAsync(string keyword)
        {
            keyword = keyword.ToLowerInvariant();
            
            return await _dbContext.Files
                .Where(f => f.FileName.ToLower().Contains(keyword) || 
                           (f.Remark != null && f.Remark.ToLower().Contains(keyword)))
                .OrderByDescending(f => f.CreateTime)
                .ToListAsync();
        }

        public async Task<List<FileItem>> GetFilesByDateRangeAsync(DateTime startDate, DateTime endDate)
        {
            return await _dbContext.Files
                .Where(f => f.CreateTime >= startDate && f.CreateTime <= endDate)
                .OrderByDescending(f => f.CreateTime)
                .ToListAsync();
        }

        #endregion

        #region 文件操作方法

        public async Task MarkFileAsImportantAsync(int fileId, bool isImportant)
        {
            var file = await _dbContext.Files.FindAsync(fileId);
            if (file != null)
            {
                file.IsImportant = isImportant;
                await _dbContext.SaveChangesAsync();
            }
        }

        public async Task UpdateFileRemarkAsync(int fileId, string remark)
        {
            var file = await _dbContext.Files.FindAsync(fileId);
            if (file != null)
            {
                file.Remark = remark;
                await _dbContext.SaveChangesAsync();
            }
        }

        public async Task DeleteFileAsync(int fileId, bool deletePhysicalFile = false)
        {
            var file = await _dbContext.Files.FindAsync(fileId);
            if (file != null)
            {
                if (deletePhysicalFile && File.Exists(file.FilePath))
                {
                    try
                    {
                        File.Delete(file.FilePath);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"删除文件时出错: {ex.Message}");
                    }
                }
                else if (File.Exists(file.FilePath))
                {
                    try
                    {
                        // 移动到回收站
                        Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(
                            file.FilePath,
                            Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs,
                            Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"移动文件到回收站时出错: {ex.Message}");
                    }
                }

                _dbContext.Files.Remove(file);
                await _dbContext.SaveChangesAsync();
            }
        }

        public void OpenFile(string filePath)
        {
            if (File.Exists(filePath))
            {
                try
                {
                    Process.Start(new ProcessStartInfo
                    {
                        FileName = filePath,
                        UseShellExecute = true
                    });
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"打开文件时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                MessageBox.Show("文件不存在或已被移动/删除", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        public void OpenFileLocation(string filePath)
        {
            if (File.Exists(filePath))
            {
                try
                {
                    Process.Start("explorer.exe", $"/select,\"{filePath}\"");
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"打开文件位置时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                MessageBox.Show("文件不存在或已被移动/删除", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        #endregion

        #region 标签管理

        public async Task<List<Tag>> GetAllTagsAsync()
        {
            return await _dbContext.Tags.OrderBy(t => t.Name).ToListAsync();
        }

        public async Task<Tag> AddTagAsync(string tagName)
        {
            var existingTag = await _dbContext.Tags.FirstOrDefaultAsync(t => t.Name == tagName);
            if (existingTag != null)
                return existingTag;

            var tag = new Tag { Name = tagName };
            _dbContext.Tags.Add(tag);
            await _dbContext.SaveChangesAsync();
            return tag;
        }

        public async Task AddFileTagAsync(int fileId, int tagId)
        {
            var existingRelation = await _dbContext.FileTagRelations
                .FirstOrDefaultAsync(ft => ft.FileId == fileId && ft.TagId == tagId);

            if (existingRelation == null)
            {
                _dbContext.FileTagRelations.Add(new FileTagRelation
                {
                    FileId = fileId,
                    TagId = tagId
                });
                await _dbContext.SaveChangesAsync();
            }
        }

        public async Task RemoveFileTagAsync(int fileId, int tagId)
        {
            var relation = await _dbContext.FileTagRelations
                .FirstOrDefaultAsync(ft => ft.FileId == fileId && ft.TagId == tagId);

            if (relation != null)
            {
                _dbContext.FileTagRelations.Remove(relation);
                await _dbContext.SaveChangesAsync();
            }
        }

        #endregion

        #region 聊天对象管理

        public async Task<List<ChatObject>> GetAllChatObjectsAsync()
        {
            return await _dbContext.ChatObjects.OrderBy(c => c.Name).ToListAsync();
        }

        public async Task UpdateChatObjectNameAsync(int chatObjectId, string newName)
        {
            var chatObject = await _dbContext.ChatObjects.FindAsync(chatObjectId);
            if (chatObject != null)
            {
                chatObject.Name = newName;
                await _dbContext.SaveChangesAsync();
            }
        }

        #endregion

        #region 维护操作

        public async Task CleanupInvalidIndexesAsync()
        {
            var allFiles = await _dbContext.Files.ToListAsync();
            int removedCount = 0;

            foreach (var file in allFiles)
            {
                if (!File.Exists(file.FilePath))
                {
                    _dbContext.Files.Remove(file);
                    removedCount++;
                }
            }

            if (removedCount > 0)
            {
                await _dbContext.SaveChangesAsync();
                MessageBox.Show($"已清理 {removedCount} 个无效索引", "清理完成", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            else
            {
                MessageBox.Show("没有发现无效索引", "清理完成", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        #endregion
    }
}